﻿using BarManager.Core.DomainModel;
using BarManager.Core.Entity;
using BarManager.Infrastructure.Data.Mapping;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using System.Transactions;

namespace BarManager.Infrastructure.Data
{
    public class ObjectContext : DbContext, IObjectContext, IUnitOfWork
    {
        #region DbContext
        public DbSet<Cargo> Cargo { get; set; }
        public DbSet<Categoria> Categoria { get; set; }
        public DbSet<Cliente> Cliente { get; set; }
        public DbSet<Domicilio> Domicilio { get; set; }
        public DbSet<Empleado> Empleado { get; set; }
        public DbSet<Envio> Envio { get; set; }
        public DbSet<EnvioDetalleBase> EnvioDetalleBase { get; set; }
        public DbSet<Orden> Orden { get; set; }
        public DbSet<OrdenDetalleBase> OrdenDetalleBase { get; set; }       
        public DbSet<Pool> Pool { get; set; }
        public DbSet<Producto> Producto { get; set; }
        public DbSet<Promocion> Promocion { get; set; }
        public DbSet<PromocionDetalle> PromocionDetalle { get; set; }
        public DbSet<Proveedor> Proveedor { get; set; }
        public DbSet<Zona> Zona { get; set; }
        public DbSet<Mesa> Mesa { get; set; }

        public ObjectContext()
        {
            // Database.SetInitializer(new DropCreateDatabaseAlways<ObjectContext>());
            //Database.SetInitializer<ObjectContext>(new DropCreateDatabaseAlways<ObjectContext>());
            //Database.SetInitializer(new DropCreateDatabaseIfModelChanges<ObjectContext>());
            Database.SetInitializer(new CreateDatabaseIfNotExists<ObjectContext>());
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingEntitySetNameConvention>();
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

            modelBuilder.Configurations.Add(new CargoMap());
            modelBuilder.Configurations.Add(new CategoriaMap());
            modelBuilder.Configurations.Add(new ClienteMap());
            modelBuilder.Configurations.Add(new DomicilioMap());            
            modelBuilder.Configurations.Add(new EmpleadoMap());
            modelBuilder.Configurations.Add(new EnvioMap());
            modelBuilder.Configurations.Add(new EnvioDetalleProductoMap());
            modelBuilder.Configurations.Add(new EnvioDetallePromocionMap());
            modelBuilder.Configurations.Add(new MesaMap());
            modelBuilder.Configurations.Add(new OrdenMap());  
            modelBuilder.Configurations.Add(new OrdenDetalleProductoMap());
            modelBuilder.Configurations.Add(new OrdenDetallePromocionMap());
            modelBuilder.Configurations.Add(new PoolMap());
            modelBuilder.Configurations.Add(new ProductoMap());
            modelBuilder.Configurations.Add(new PromocionMap());
            modelBuilder.Configurations.Add(new PromocionDetalleMap());
            modelBuilder.Configurations.Add(new ProveedorMap());
            modelBuilder.Configurations.Add(new ZonaMap());

            base.OnModelCreating(modelBuilder);
        }
        #endregion

        #region IObjectContext
        public IQueryable<TEntity> Query<TEntity>() where TEntity : class
        {
            return base.Set<TEntity>();
        }

        public TEntity Create<TEntity>() where TEntity : class
        {
            var entity = base.Set<TEntity>().Create();
            this.Add<TEntity>(entity);
            return entity;
        }

        public void Update<TEntity>(TEntity entity) where TEntity : class
        {
            var entityObj = base.Entry(entity);
            if (entityObj.State == EntityState.Detached)
                base.Set<TEntity>().Attach(entityObj.Entity);
            entityObj.State = EntityState.Modified;
        }

        public void Add<TEntity>(TEntity entity) where TEntity : class
        {
            base.Set<TEntity>().Add(entity);
        }

        public void Delete<TEntity>(TEntity entity) where TEntity : class
        {
            var entityObj = base.Entry(entity);
            if (entityObj.State == EntityState.Detached)
                base.Set<TEntity>().Attach(entityObj.Entity);
            base.Set<TEntity>().Remove(entity);
        }
        #endregion

        #region IUnitOfWork
        public void Commit()
        {
            //try
            //{
                base.SaveChanges();
            //}
            //catch (System.Exception ex)
            //{
                
            //    throw;
            //}
        }

        public TransactionScope StartTransaction()
        {
            return new TransactionScope();
        }
        #endregion
    }
}
